package com.leemon.mall.security.handler;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;

/**
 * @author limenglong
 * @create 2019-09-16 18:25
 * @desc 登陆成功处理
 **/
@Component
public class LoginAuthSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthorizationServerTokenServices tokenServices;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //security默认的是SavedRequestAwareAuthenticationSuccessHandler，在登录成功后做了请求重定向处理
        //此处是模仿TokenEndpoint的oauth/token接口 来生成token,从而替代调用oauth/token接口

        try {
            String grant_type = request.getParameter(OAuth2Utils.GRANT_TYPE);

            ClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
            String clientId = authentication.getName();


            ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(clientId);

            //简化创建tokenRequest
            TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, Sets.newHashSet(), grant_type);
//        OAuth2RequestFactory oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetailsService);
//        TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);

            //创建Oauth2Request
            OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(authenticatedClient);
            //创建OAuth2Authentication认证信息
            OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);

            //从使用默认的方法获取token
            OAuth2AccessToken accessToken = tokenServices.createAccessToken(oAuth2Authentication);


            response.setCharacterEncoding(CharsetUtil.UTF_8);
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);

            response.getWriter().append(objectMapper.writeValueAsString(accessToken));
        } catch (Exception e) {
            throw new BadCredentialsException("Failed to decode basic authentication token");
        }

    }
}
